package com.pzhu.user.rpc.server;

import com.google.protobuf.Empty;
import com.pzhu.base.common.utils.exceptions.Assert;
import com.pzhu.user.api.RoleApi;
import com.pzhu.user.api.RoleServiceGrpc;
import com.pzhu.user.domain.dto.converter.RoleDtoConverter;
import com.pzhu.user.domain.ro.RoleCreateRO;
import com.pzhu.user.domain.ro.RoleSearchRO;
import com.pzhu.user.domain.ro.RoleUpdateRO;
import com.pzhu.user.domain.vo.RoleSearchVO;
import com.pzhu.user.service.impl.RoleService;
import io.grpc.stub.StreamObserver;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import net.devh.boot.grpc.server.service.GrpcService;

@GrpcService
@RequiredArgsConstructor
public class RoleServer extends RoleServiceGrpc.RoleServiceImplBase {

    private final RoleService roleService;

    private final RoleDtoConverter roleDtoConverter;

    @Override
    public void createRole(RoleApi.RoleCreateRequest request, StreamObserver<RoleApi.RoleCreateResponse> responseObserver) {
        try {
            RoleApi.RoleCreateDTO roleCreateDTO = request.getRole();
            RoleCreateRO roleCreateRO = roleDtoConverter.convert(roleCreateDTO);
            Long roleId = roleService.save(roleCreateRO);
            
            RoleApi.RoleCreateResponse.Builder builder = RoleApi.RoleCreateResponse.newBuilder();
            Optional.ofNullable(roleId).ifPresent(builder::setRoleId);
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void getRoleById(RoleApi.GetRoleRequest request, StreamObserver<RoleApi.RoleResponse> responseObserver) {
        try {
            Long roleId = request.getRoleId();
            RoleSearchVO roleSearchVO = roleService.info(roleId);
            Assert.assertNotNull(roleSearchVO, "角色不存在");
            
            RoleApi.RoleDTO roleDTO = roleDtoConverter.toDTO(roleSearchVO);
            RoleApi.RoleResponse.Builder builder = RoleApi.RoleResponse.newBuilder();
            responseObserver.onNext(builder.setRole(roleDTO).build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void getRoleByCode(RoleApi.GetRoleByCodeRequest request, StreamObserver<RoleApi.RoleResponse> responseObserver) {
        try {
            String roleCode = request.getRoleCode();
            RoleSearchVO roleSearchVO = roleService.searchOne(RoleSearchRO.builder().roleCode(roleCode).build());
            Assert.assertNotNull(roleSearchVO, "角色不存在");
            
            RoleApi.RoleDTO roleDTO = roleDtoConverter.toDTO(roleSearchVO);
            RoleApi.RoleResponse.Builder builder = RoleApi.RoleResponse.newBuilder();
            responseObserver.onNext(builder.setRole(roleDTO).build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void updateRole(RoleApi.UpdateRoleRequest request, StreamObserver<RoleApi.RoleResponse> responseObserver) {
        try {
            Long roleId = request.getRoleId();
            RoleApi.RoleUpdateDTO roleUpdateDTO = request.getRole();
            RoleUpdateRO roleUpdateRO = roleDtoConverter.convertUpdate(roleUpdateDTO);
            
            boolean result = roleService.update(roleId, roleUpdateRO);
            Assert.assertTrue(result, "更新角色失败");
            
            RoleSearchVO roleSearchVO = roleService.info(roleId);
            RoleApi.RoleDTO roleDTO = roleDtoConverter.toDTO(roleSearchVO);
            RoleApi.RoleResponse.Builder builder = RoleApi.RoleResponse.newBuilder();
            responseObserver.onNext(builder.setRole(roleDTO).build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void deleteRole(RoleApi.DeleteRoleRequest request, StreamObserver<Empty> responseObserver) {
        try {
            Long roleId = request.getRoleId();
            boolean result = roleService.removeById(roleId);
            Assert.assertTrue(result, "删除角色失败");
            
            responseObserver.onNext(Empty.newBuilder().build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void batchDeleteRoles(RoleApi.BatchDeleteRolesRequest request, StreamObserver<Empty> responseObserver) {
        try {
            List<Long> roleIds = request.getRoleIdsList();
            boolean result = roleService.removeByIds(roleIds);
            Assert.assertTrue(result, "批量删除角色失败");
            
            responseObserver.onNext(Empty.newBuilder().build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void getAllRoles(RoleApi.GetAllRolesRequest request, StreamObserver<RoleApi.GetAllRolesResponse> responseObserver) {
        try {
            List<RoleSearchVO> roles = roleService.getAllRoles();
            List<RoleApi.RoleDTO> roleDTOs = roles.stream()
                    .map(roleDtoConverter::toDTO)
                    .collect(Collectors.toList());
            
            RoleApi.GetAllRolesResponse.Builder builder = RoleApi.GetAllRolesResponse.newBuilder();
            builder.addAllRoles(roleDTOs);
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void assignRoleToUser(RoleApi.AssignRoleToUserRequest request, StreamObserver<Empty> responseObserver) {
        try {
            Long userId = request.getUserId();
            Long roleId = request.getRoleId();
            boolean result = roleService.assignRoleToUser(userId, roleId);
            Assert.assertTrue(result, "分配角色给用户失败");
            
            responseObserver.onNext(Empty.newBuilder().build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void removeRoleFromUser(RoleApi.RemoveRoleFromUserRequest request, StreamObserver<Empty> responseObserver) {
        try {
            Long userId = request.getUserId();
            Long roleId = request.getRoleId();
            boolean result = roleService.removeRoleFromUser(userId, roleId);
            Assert.assertTrue(result, "从用户移除角色失败");
            
            responseObserver.onNext(Empty.newBuilder().build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }

    @Override
    public void getUserRoles(RoleApi.GetUserRolesRequest request, StreamObserver<RoleApi.GetUserRolesResponse> responseObserver) {
        try {
            Long userId = request.getUserId();
            List<RoleSearchVO> userRoles = roleService.getUserRoles(userId);
            List<RoleApi.RoleDTO> roleDTOs = userRoles.stream()
                    .map(roleDtoConverter::toDTO)
                    .collect(Collectors.toList());
            
            RoleApi.GetUserRolesResponse.Builder builder = RoleApi.GetUserRolesResponse.newBuilder();
            builder.addAllRoles(roleDTOs);
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(e);
        }
    }
}